package com.cvit.weixin;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;
import org.w3c.dom.Document;

import com.cvit.model.Callback;
import com.cvit.model.Orders;
import com.cvit.model.Student;
import com.cvit.service.OrdersService;
import com.cvit.service.StudentService;
import com.cvit.utils.CrossOriginControl;
import com.cvit.utils.Msg;
import com.cvit.utils.Utils;

import schemasMicrosoftComOfficeOffice.ShapelayoutDocument;


@Controller
public class WeiXinController {
	
	@Autowired
	StudentService studentService;
	@Autowired
	OrdersService ordersService;
	
	private static String baseUrl = "http://ykbmfs.zs.cvit.com.cn";
	//log4j
	private static Logger logger = Logger.getLogger(WeiXinController.class);
	
	String paySign="";
	
	/**
	 * @author WYHY
	 * 生成openid
	 * */
	@RequestMapping("/userAuth")
	public String userAuth(HttpServletRequest request, HttpServletResponse response){
		logger.info("*----------- 微信公众号支付流程开始 ----------*");
		try {
			//授权后要跳转的链接
			String backUri = baseUrl + "/artadmissions/details.html";
			//URLEncoder.encode 后可以在backUri 的url里面获取传递的所有参数
			backUri = URLEncoder.encode(backUri);
			//scope 参数视各自需求而定，这里用scope=snsapi_base 不弹出授权页面直接授权目的只获取统一支付接口的openid
			String url = "http://wx.yuanruish.cn/OAuth/StartAuth?" +
					"appid=" + ConfigUtil.appid +
					"&state="+ConfigUtil.key+
					"&componentappid=wx704d0b883a88475f"+
					"&redirect_uri=" +backUri+
					"&scope=snsapi_base";
			//http://wx2.yuanruish.cn/OAuth/StartAuth?appid=wx73146a0bfcc21346&componentappid=wx3d06e4fc2949bf51&scope=snsapi_base&redirect_uri=http://xxx.cvit.com.cn/apayadadfa/adasdfa
			
			System.out.println("url:" + url);
			//log4j--star
			logger.info("授权url："+url);
    		//log4j--end
			response.sendRedirect(url);
		} catch (IOException e) {
			e.printStackTrace();
			logger.info("授权失败,报错："+e.getMessage(),e);
		}
		return null;
	}
	
	
	/**
     * 微信统一下单接口
     * @param
     * @param 
     * 
     */
   @RequestMapping("/weixinpay")
   @ResponseBody
   public Map WeiXinpay(HttpServletResponse resp,HttpServletRequest request) throws IOException{
	   String studentid=request.getParameter("studentid");
	   String openid =request.getParameter("openid");// "oOVt-03tpb6BNr8SCYF1stYz-z6c";
	   Map<String, Object> map=new HashMap<String, Object>();
	   Map<String, Object> returnMap=new HashMap<String, Object>();
	   DataInputStream input = null;  
	   Date newdate=new Date();
	   Student student = studentService.getStudentById(studentid);
	   String body=student.getSchool()+"-"+student.getMajor()+"-"+student.getName();
	   String out_trade_no=ordersService.JudgeIdRepeat();
	   java.io.ByteArrayOutputStream out = null;
	   HttpServletRequest httpServletRequest = (HttpServletRequest)request;
	   String spbill_create_ip= httpServletRequest.getRemoteAddr();
	   try{    
	   map.put("appid", ConfigUtil.appid);
	   map.put("body",body);
	   map.put("device_info", "WEB");
	   map.put("fee_type","CNY");
	   map.put("limit_pay", "no_credit");
	   map.put("mch_id", ConfigUtil.mch_id);
	   map.put("nonce_str", Utils.getUUID());
	   map.put("notify_url", baseUrl+"/weixincallback");
	   map.put("out_trade_no",out_trade_no);
//	   map.put("sub_appid", ConfigUtil.sub_appid);
	   map.put("sub_mch_id", ConfigUtil.sub_mch_id);
//	   map.put("sub_openid", openid);
	   map.put("openid", openid);
	   map.put("sign_type", "MD5");
	   map.put("spbill_create_ip", spbill_create_ip);
	   map.put("total_fee", student.getPrice());
	   map.put("trade_type", "JSAPI");
	   String sign = Signature.getSign(map, ConfigUtil.key);
	   map.put("sign", sign);
	   String xmlString = WXXmlSp.getXmlOrder(map);
	   //log4j--star
	   logger.info("统一下单参数xml："+xmlString);
	   //log4j--end
			byte[] xmlData = xmlString.getBytes("UTF-8");
			String urlStr = ConfigUtil.UNIFIED_ORDER_URL;
			// 获得到位置服务的链接  
			URL url = new URL(urlStr);
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();    
			connection.setRequestMethod("POST");  
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			// 将xml数据发送到位置服务
			connection.setRequestProperty("Content-Type", "text/xml");
			connection.setRequestProperty("Content-length",
					String.valueOf(xmlData.length));
			DataOutputStream printout = new DataOutputStream(
					connection.getOutputStream());
			printout.write(xmlData);
			printout.flush();
			printout.close();
			input = new DataInputStream(connection.getInputStream());
			byte[] rResult;
			out = new java.io.ByteArrayOutputStream();
			byte[] bufferByte = new byte[256];
			int l = -1;
			int downloadSize = 0;
			while ((l = input.read(bufferByte)) > -1) {
				downloadSize += l;
				out.write(bufferByte, 0, l);
				out.flush();
			}
			rResult = out.toByteArray();
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document d = db.parse(new ByteArrayInputStream(rResult));
			String return_code = d.getElementsByTagName("return_code").item(0).getFirstChild().getNodeValue();
			String result_code="";
			if(return_code.equals("SUCCESS")){
				result_code = d.getElementsByTagName("result_code").item(0).getFirstChild().getNodeValue();
			}
			if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)){
				
				Orders orders=new Orders();
				orders.setId(out_trade_no);
				orders.setOpenid(studentid);
				orders.setExamineeId(student.getExamineeId());
				orders.setCardId(student.getCardId());
				orders.setName(student.getName());
				orders.setSchool(student.getSchool());
				orders.setMajor(student.getMajor());
				orders.setPrice(student.getPrice());
				orders.setStartTime(newdate);
				ordersService.addOrders(orders);
				String t = String.valueOf( new Date().getTime() / 1000);
				returnMap.put("appId",ConfigUtil.appid);
				returnMap.put("nonceStr",Utils.getUUID());
				returnMap.put("package","prepay_id="+d.getElementsByTagName("prepay_id").item(0).getFirstChild().getNodeValue());
				returnMap.put("signType","MD5");
				returnMap.put("timeStamp",t);
				paySign = Signature.getSign(returnMap, ConfigUtil.key);
				returnMap.put("paySign", paySign);
				returnMap.put("orderid", out_trade_no);
				logger.info("统一下单成功，订单："+orders);
				logger.info("返回map："+returnMap);
			}else{
				//returnMap.put("recode", "0");
				if(!return_code.equals("SUCCESS")){
					System.out.println("return失败:"+d.getElementsByTagName("return_msg").item(0).getFirstChild().getNodeValue());
					returnMap.put("msg", d.getElementsByTagName("return_msg").item(0).getFirstChild().getNodeValue());
				}else if(!result_code.equals("SUCCESS")){
					System.out.println("result失败:"+d.getElementsByTagName("err_code_des").item(0).getFirstChild().getNodeValue());
					returnMap.put("msg", d.getElementsByTagName("err_code_des").item(0).getFirstChild().getNodeValue());
				}
			}
			
		} catch (Exception e){
			e.printStackTrace();
			logger.info("统一下单失败,报错："+e.getMessage(),e);
		} finally {
			out.close();
			input.close();
		}
		return returnMap;
//	   return h5url; 
   }

    String oopenid="";
	String sign="";
	String total_fee="";
	String orderId="";
	String transaction_id="";
   @RequestMapping("/weixincallback")
   @ResponseBody
    public String WeiXinCallBack(HttpServletResponse resp,HttpServletRequest reques){
		try {
//			orederid=null;
			ServletInputStream input=reques.getInputStream();
			byte[] rResult;
			ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
			byte[] bufferByte = new byte[256];
			int l = -1;
			int downloadSize = 0;
			while ((l = input.read(bufferByte)) > -1) {
				downloadSize += l;
				out.write(bufferByte, 0, l);
				out.flush();
			}
			rResult = out.toByteArray();
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document d = db.parse(new ByteArrayInputStream(rResult));
			String return_code = d.getElementsByTagName("return_code").item(0).getFirstChild().getNodeValue();
			String result_code = d.getElementsByTagName("result_code").item(0).getFirstChild().getNodeValue();
			if("SUCCESS".equals(return_code)&&"SUCCESS".equals(result_code)){
				sign=d.getElementsByTagName("sign").item(0).getFirstChild().getNodeValue();
				total_fee=d.getElementsByTagName("total_fee").item(0).getFirstChild().getNodeValue();
				orderId=d.getElementsByTagName("out_trade_no").item(0).getFirstChild().getNodeValue();
				transaction_id=d.getElementsByTagName("transaction_id").item(0).getFirstChild().getNodeValue();
				Map<String, String> XMLmap=new HashMap<>();
				XMLmap.put("sign", sign);
				XMLmap.put("total_fee", total_fee);
				XMLmap.put("orderId", orderId);
				XMLmap.put("transaction_id", transaction_id);
				String xml=WXXmlSp.mapToXml(XMLmap);
				//log4j--star
				logger.info("微信回调xml:"+xml);
				//log4j--end
				Callback callback=new Callback();
				callback.setOrderid(orderId);
				callback.setTransactionId(transaction_id);
				callback.setXml(xml);
				ordersService.insCallback(callback);
				oopenid=ordersService.selectOpenid(orderId);
				if(oopenid!=""){
					ordersService.updatePayType(orderId);
					studentService.updatePayType(oopenid);
					reques.setAttribute("out_trade_no", orderId);
					reques.setAttribute("sign", sign);
					reques.setAttribute("total_fee", total_fee);
					resp.getWriter().write(RequestHandler.setXML("SUCCESS", ""));
				}
				logger.info("*----------- 微信公众号支付流程结束 ----------*");
			}
			
		} catch (Exception e) {
		try {
			resp.getWriter().write(RequestHandler.setXML("FAIL", "error"));
           } catch (IOException e1) {
               e1.printStackTrace();
               logger.info("微信回调失败,报错："+e.getMessage(),e);
           }
		}
	   return null;
    }
   
	/**
	 * @author WYHY
	 * 关闭订单
	 * */
	@RequestMapping("/close")
	public String close(HttpServletRequest request, HttpServletResponse response,String orderid) throws IOException{
		   //log4j--star
			//log4j--end
		   Map<String, Object> map=new HashMap<String, Object>();
		   Map<String, Object> returnMap=new HashMap<String, Object>();
		   DataInputStream input = null;  
		   java.io.ByteArrayOutputStream out = null;
		   try{    
			   map.put("appid", ConfigUtil.appid);
			   map.put("mch_id", ConfigUtil.mch_id);
//			   map.put("sub_appid", ConfigUtil.sub_appid);
			   map.put("sub_mch_id", ConfigUtil.sub_mch_id);
			   map.put("out_trade_no",orderid);
			   map.put("nonce_str", orderid);
			   String sign = Signature.getSign(map, ConfigUtil.key);
			   map.put("sign", sign);
			   String xmlString = WXXmlSp.getCloseXmlOrder(map);
			   //log4j--star
				logger.info("微信关单xml:"+xmlString);
				//log4j--end
				byte[] xmlData = xmlString.getBytes("UTF-8");
				String urlStr = "https://api.mch.weixin.qq.com/pay/closeorder";
				URL url = new URL(urlStr);
				HttpURLConnection connection = (HttpURLConnection)url.openConnection();    
				connection.setRequestMethod("POST");  
				connection.setDoOutput(true);
				connection.setDoInput(true);
				connection.setUseCaches(false);
				// 将xml数据发送到位置服务
				connection.setRequestProperty("Content-Type", "text/xml");
				connection.setRequestProperty("Content-length",
						String.valueOf(xmlData.length));
				DataOutputStream printout = new DataOutputStream(
						connection.getOutputStream());
				printout.write(xmlData);
				printout.flush();
				printout.close();
				input = new DataInputStream(connection.getInputStream());
				byte[] rResult;
				out = new java.io.ByteArrayOutputStream();
				byte[] bufferByte = new byte[256];
				int l = -1;
				int downloadSize = 0;
				while ((l = input.read(bufferByte)) > -1) {
					downloadSize += l;
					out.write(bufferByte, 0, l);
					out.flush();
				}
				rResult = out.toByteArray();
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				DocumentBuilder db = dbf.newDocumentBuilder();
				Document d = db.parse(new ByteArrayInputStream(rResult));
				String return_code = d.getElementsByTagName("return_code").item(0).getFirstChild().getNodeValue();
				String result_code="";
				if(return_code.equals("SUCCESS")){
					result_code = d.getElementsByTagName("result_code").item(0).getFirstChild().getNodeValue();
				}
				if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)){
					logger.info("关单成功");
					logger.info("*----------- 微信公众号支付流程结束 ----------*");
				}else{
					if(!return_code.equals("SUCCESS")){
						System.out.println("return失败:"+d.getElementsByTagName("return_msg").item(0).getFirstChild().getNodeValue());
						returnMap.put("msg", d.getElementsByTagName("return_msg").item(0).getFirstChild().getNodeValue());
					}else if(!result_code.equals("SUCCESS")){
						System.out.println("result失败:"+d.getElementsByTagName("err_code_des").item(0).getFirstChild().getNodeValue());
						returnMap.put("msg", d.getElementsByTagName("err_code_des").item(0).getFirstChild().getNodeValue());
					}
					
				}
				
			} catch (Exception e){
				//returnMap.put("recode", "2");
				e.printStackTrace();
				logger.info("关闭订单失败,报错："+e.getMessage(),e);
			} finally {
				out.close();
				input.close();
			}
		return null;
	}
   
}
